/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package analiseSintatica.Regras.Expressoes;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.Regra;
import analiseSintatica.estruturadados.NoArvore;

import java.util.LinkedList;

/**
 *
 * @author matheus
 */
public class RegraMultiplicacao extends Regra {

    protected static Regra instancia;

    
    protected String estrutura = "<cast> {<op_multiplicacao> <cast>}";
    
    /**
     * Construtor privado necessario ao singleton
     */
    private RegraMultiplicacao() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraMultiplicacao getInstance() {
        if (instancia == null) {
            instancia = new RegraMultiplicacao();
        }
        return (RegraMultiplicacao) instancia;
    }

    @Override
    public NoArvore analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
        ErroSintaticoException erros = new ErroSintaticoException();

        NoArvore naoterminalmultiplicacao = new NoArvore("<multiplicacao>", false);

        try{
            naoterminalmultiplicacao.adicionaFilho(RegraCast.getInstance().analisar(listaTokens));
        }catch(ErroSintaticoException e){
            while (e.size() != 0) {
                erros.addErros(e.getErros());
            }
        }

        while((RegraOpMultiplicacao.getInstance().getPrimeiro().contains(listaTokens.getFirst().getLexema())||
                RegraOpMultiplicacao.getInstance().getPrimeiro().contains(listaTokens.getFirst().getToken()))){
            try{
                naoterminalmultiplicacao.adicionaFilho(RegraOpMultiplicacao.getInstance().analisar(listaTokens));
            }catch(ErroSintaticoException e){
                while (e.size() != 0) {
                    erros.addErros(e.getErros());
                }
            }
            try{
                naoterminalmultiplicacao.adicionaFilho(RegraCast.getInstance().analisar(listaTokens));
            }catch(ErroSintaticoException e){
                while (e.size() != 0) {
                    erros.addErros(e.getErros());
                }
            }
        }

        if (erros.size() != 0) {
            throw erros;
        }

        return naoterminalmultiplicacao;
    }


    @Override
    protected void setPrimeiro() {
        //{'{'} U {identificador, "(", numeroInteiro , numeroFlutuante , charconst, '++', '--', '&', '*'}
        primeiro.add("(");
        primeiro.add("{");
        primeiro.add("identificador");
        primeiro.add("numeroInteiro");
        primeiro.add("numeroFlutuante");
        primeiro.add("charconst");
        primeiro.add("++");
        primeiro.add("--");
        primeiro.add("&");
        primeiro.add("*");
    }

    @Override
    protected void setSeguinte() {
        /*{"+" , "-"} U {"<" , "<=" , ">" , ">="} U {"==" , "!=" } U {&&}
         U {'{'} U {identificador, "(", numeroInteiro , numeroFlutuante , charconst, '++', '--', '&', '*'}
                        U {";", ",", "}" ")"}*/

        seguinte = primeiro;
        seguinte.add("+");
        seguinte.add("-");
        seguinte.add("<");
        seguinte.add("<=");
        seguinte.add(">");
        seguinte.add(">=");
        seguinte.add("==");
        seguinte.add("!=");
        seguinte.add("&&");
        seguinte.add(";");
        seguinte.add(",");
        seguinte.add("}");
        seguinte.add(")");

    }
}
